import type {BbsCodeNode} from "../types/BbsCodeNode.ts";


const findAllDice = (nodes: BbsCodeNode[] | undefined): BbsCodeNode[] => {
    const res: BbsCodeNode[] = []
    if (!nodes || !nodes.length) return res
    for (const node of nodes) {
        if (node.type === 'dice') {
            res.push(node)
        } else {
            res.push(...findAllDice(node.children))
        }
    }

    return res
}
const diceRange = (seed: number, range: number): { seed: number, result: number } => {
    let newSeed = (seed * 9301 + 49297) % 233280
    let result = Math.floor(newSeed / 233280 * range) + 1
    return {seed: newSeed, result}
}

const dice = (node: BbsCodeNode, seed: number): number => {
    const expression = node.params
    if (!expression) return seed
    // console.log(expression)
    // 结果总和
    let sum = 0
    // 计算过程和结果
    const resultText: string[] = []
    // 拆分算式
    const expressions = expression.split("\+").map(i => i.trim());
    // 对算式进行分组计算
    for (const ex of expressions) {
        const matcher = /^(\d*)d(\d+)$/.exec(ex)
        if (matcher) {
            // 骰子数量
            const count = Number(matcher?.[1] || "1")
            const range = Number(matcher[2])
            for (let i = 0; i < count; i++) {
                const {seed: newSeed, result} = diceRange(seed, range)
                seed = newSeed
                sum += result
                resultText.push(`d${range}(${result})`)
            }

        } else if (!isNaN(Number(ex))) {
            // 固定数字
            sum += Number(ex)
            resultText.push(ex)
        } else {
            resultText.push("格式错误")
        }
    }

    // 全部分组计算完毕, 输出计算过程

    node.text = `${expression} = ${resultText.join(" + ")} = ${sum}`

    return seed
}


export const calculate = (nodes: BbsCodeNode[] | undefined, initSeed: number) => {
    if (!nodes) return
    //  找出所有的dice标签
    const allDice = findAllDice(nodes)
    // 没有dice标签，结束执行
    if (!allDice.length) return
    //  按照 collapse外 > collapse内排序
    const sortedDice: BbsCodeNode[] = []
    sortedDice.push(...allDice.filter(node => !node.inCollapse))
    sortedDice.push(...allDice.filter(node => node.inCollapse))

    // 初始化种子,如果第一个dice在collapse中，种子+1
    let seed = initSeed + (sortedDice[0].inCollapse ? 1 : 0)
    // 计算每一个dice的随机结果, 每次计算后返回种子
    for (const node of sortedDice) {
        seed = dice(node, seed)
    }
}


